
// 计算约瑟夫变相环
/*
julia代码 变相约瑟夫环。知乎上一个小米面试题的微软解法（细节去知乎找找看）

原题： 一副从1到n的牌，每次从牌堆顶取一张放桌子上，再取一张放牌堆底，直到手机没牌，最后桌子上的牌是从1到n有序，设计程序，输入n，输出牌堆的顺序数组 。

 微软君给的算法： 取一个1～n的数组，这里为了说明取n=5。按照题目中的规则变换，得到数组：[1 3 5 4 2]，将该数组下标与值互换得到[1 5 2 4 3]，即为答案。解释：[1 3 5 4 2]的意义是，经过变换，原数组中3号位置的数字现在2号槽，原数组中5号位置的数字现在3号槽... 现在已知变换后的槽存放的是1～n，故只需将下标与值互换即可得到待求数组。
*/

// joseph2

// 构成一个Vec队列
fn make_array(num: i32) -> Vec<i32>{
    let mut v = Vec::new();
    for element in 1..(num+1) {
        v.push(element);
    }
    return v;
}
// 根据原始数据构成一个中间Vec
fn count_mid_array(array: &mut Vec<i32>) -> Vec<i32>{
    let mut v = Vec::new();
    while array.len() > 1{ // 长度大1
        let t1 = array.remove(0); // 移除首个
        v.push(t1); // 插入中间组
        let t2 = array.remove(0); // 再移除首个
        array.push(t2); // 插入到原组结尾
    }
    v.push(array[0]); // 插入剩余的最后一个
    return v;
}

// 转换结果数组
fn trans_array(n: i32, new_array: Vec<i32>) -> Vec<i32>{
    let mut fin_array = Vec::new();
    for i in 1..(n + 1) { 
        for (pos, e) in new_array.iter().enumerate(){ // 带索引
            if i == *e{ // 这里对比值要*解引用
                fin_array.push((pos+1) as i32); // 插入，pos是usize要转换一下
            }
        }
    }
    return fin_array
}

// 测试程序入口
pub fn joseph2_test(){
    let n = 12;
    let mut v = make_array(n);
    println!("原始数组 {:?}", v);
    let v2 = count_mid_array(&mut v);
    println!("计算中间组 {:?}", v2);
    let fin_v = trans_array(n, v2);
    println!("最终结果： {:?}", fin_v);
}


